#include "MapMgr.h"
#include "Map.h"
#include "base/core/os/debug.h"
#include "base/core/lua_parser.h"
#include "Character/monster/MonsterRefMgr.h"
#include "Character/monster/MonsterRefCfg.h"
#include "Common/Utility/RecastUtility.h"

static const char map_config_dir[] = "./data/map/";

MapMgr::MapMgr()
	: m_mapMap()
{}

MapMgr::~MapMgr() 
{}

bool  MapMgr::Init() 
{
	m_pMapPool = new ObjectPool<Map>;

    bool result  = false;
    bool retCode = false;

    retCode = LoadConfig();
    MMOLOG_PROCESS_ERROR(retCode);

	//必须在地图加载后面，场景加载前面
	MMOLOG_PROCESS_ERROR(g_MakeMapLocationCfg());
	if (!g_GetMapLocationCfg()->Init())
	{
		LogErrPrint("[logic] monster refresh config init fail");
		goto Exit0;
	}

	//必须在地图加载后面，场景加载前面
	MMOLOG_PROCESS_ERROR(g_MakeGeneralCreatureRefMgr());
	if (!g_GetGeneralCreatureRefMgr()->Init())
	{
		LogErrPrint("[logic] monster refresh mgr init fail");
		goto Exit0;
	}

	MMOLOG_PROCESS_ERROR(g_MakeSceneMgr());
	if (!g_GetSceneMgr()->Init())
	{
		LogErrPrint("[logic] scene mgr init fail");
		result = false;
		goto Exit0;
	}
    result = true;

Exit0:
    return result;
}

void MapMgr::UnInit() 
{
    if (! m_mapMap.empty()) 
	{
        Map* map = NULL;
        DataMap::iterator iter = m_mapMap.begin();
        DataMap::iterator iter_end = m_mapMap.end();
        for (; iter != iter_end; ++iter) 
		{
            map = iter->second;
            if (map) 
			{
                map->UnInit();
				m_pMapPool->FreeObj(map);
            }
        }
        m_mapMap.clear();
    }

	NavMeshMap::iterator iter = m_mapNavMesh.begin();
	for (; iter != m_mapNavMesh.end(); iter++)
	{
		//释放一下内存吧!!!
		MMO_FREE_NAVMESHQUERY(iter->second.pdtNavMeshQuery);
		MMO_FREE_NAVMESH(iter->second.pdtNavMesh);
		iter->second.pdtNavMesh = nullptr;
		iter->second.pdtNavMeshQuery = nullptr;
	}
	m_mapNavMesh.clear();

	//回收内存
	MMO_DELETE(m_pMapPool);
}

Map* MapMgr::GetMap(uint32_t m_id)
{
    DataMap::iterator iter = m_mapMap.find(m_id);
    if (iter != m_mapMap.end()) 
	{
        return iter->second;
    } 
	else 
	{
        return NULL;
    }
}

bool MapMgr::LoadConfig() 
{
	const MapMapCfgMap *mapConfig = g_GetMapMapCfgTable()->GetMapMapCfgMap();
	if (mapConfig != nullptr)
	{
		MapMapCfgMap::const_iterator it = mapConfig->begin();
		for (; it != mapConfig->end(); ++it)
		{
			Map* map = m_pMapPool->MallocObj();
			if (map->Init(it->first))
				AddMap(it->first, map);
			else
				LogErrFmtPrint("load map info wrong! id:%d", it->first);
		}
	}
    return true;
}

bool MapMgr::AddMap(uint32_t m_id, Map* map)
{
	DataMap::iterator iter = m_mapMap.find(m_id);
    if (iter != m_mapMap.end()) 
	{
		//LogErrFmtPrint("[logic] map(%d) is already exist", m_id);
        return false;
    }
	m_mapMap[m_id] = map;
    return true;
}

void MapMgr::DelMap(uint32_t m_id)
{
	DataMap::iterator iter = m_mapMap.find(m_id);
    MMO_ASSERT(iter != m_mapMap.end());
    if (iter != m_mapMap.end()) 
	{
        Map* map = iter->second;
        if (map) 
		{
            map->UnInit();
            m_pMapPool->FreeObj(map);
        }
        m_mapMap.erase(iter);
    }
}

MapMgr::DataMap* MapMgr::GetAllMaps()
{
	return &m_mapMap;
}

void MapMgr::AddNavMeshInfo(std::string& navName, navMeshInfo& navInfo)
{
	m_mapNavMesh[navName] = navInfo;
}

navMeshInfo* MapMgr::GetNavMeshInfo(std::string& navName)
{
	std::unordered_map<std::string, navMeshInfo>::iterator iter = m_mapNavMesh.find(navName);
	if (iter == m_mapNavMesh.end())
		return nullptr;

	return &(iter->second);
}

bool MapMgr::IsDynamic(uint32_t mapId)
{
	Map* pMap = GetMap(mapId);
	if (pMap && pMap->IsDynamic())
		return true;
	return false;
}
